﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.IO.IsolatedStorage;
using System.IO;
using System.Xml.Linq;
using System.Xml;

namespace Simp.Interpreter
{
	/// <summary>Encapsulates the logic around the recent files.</summary>
	/// <remarks>Recent files are saved in the isolated storage for the application.  Only 5 files are kept.</remarks>
	public sealed class RecentFiles
	{
		private const string CONFIG_FILE_NAME = "RecentFiles.xml";
		private const int MAX_COUNT = 5;
		private readonly List<string> _pathList;

		/// <summary>Private constructor.</summary>
		/// <param name="pathList"></param>
		private RecentFiles(IEnumerable<string> pathList)
		{
			_pathList = new List<string>(pathList);
		}

		/// <summary>Returns the recent files saved on isolated storage.</summary>
		/// <returns></returns>
		public static RecentFiles GetRecentFiles()
		{
			try
			{
				using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetStore(
					IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null))
				{
					if (isoStorage.GetFileNames(CONFIG_FILE_NAME).Length == 1)
					{
						using (var stream = new IsolatedStorageFileStream(CONFIG_FILE_NAME, FileMode.Open, isoStorage))
						{
							XElement configElement = XElement.Load(XmlReader.Create(stream));
							var pathList = from pathElement in configElement.Elements("path")
										   select pathElement.Value;

							return new RecentFiles(pathList);
						}
					}
					else
					{
						return new RecentFiles(new string[0]);
					}
				}
			}
			catch
			{
				return new RecentFiles(new string[0]);
			}
		}

		/// <summary>Returns the paths of the recent files.</summary>
		public string[] RecentFilePaths
		{
			get { return _pathList.ToArray(); }
		}

		/// <summary>Save recent files to isolated storage.</summary>
		public void Save()
		{
			using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetStore(
				IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null))
			{
				using (var stream = new IsolatedStorageFileStream(CONFIG_FILE_NAME, FileMode.Create, isoStorage))
				{
					var pathElements = from path in _pathList select new XElement("path", path);
					XElement configElement = new XElement("paths", pathElements);

					using (XmlWriter writer = XmlWriter.Create(stream))
					{
						configElement.Save(writer);
						writer.Flush();
					}
					stream.Flush();
				}
			}
		}

		/// <summary>Add a recent file.</summary>
		/// <remarks>The file will be added at the top and will push the others down.</remarks>
		/// <param name="path"></param>
		public void AddFile(string path)
		{
			_pathList.Remove(path);
			_pathList.Insert(0, path);
			if (_pathList.Count > MAX_COUNT)
			{
				_pathList.RemoveAt(MAX_COUNT);
			}
		}
	}
}